use std::borrow::BorrowMut;
use std::rc::{Rc, Weak};
use std::cell::RefCell;
use std::default::Default;
use crate::chess::{PieceColor, PointState};

#[derive(Debug)]
pub struct Point {
    id: u8,
    piece: Option<PointState>,
    v: RefCell<Weak<Edge>>,
    h: RefCell<Weak<Edge>>,
    // h: Weak<Edge>,
    // v: Weak<Edge>,
}

impl Point {
    pub fn new(id: u8) -> Point {
        Point{
            id,
            piece: None,
            h: RefCell::new(Weak::new()),
            v: RefCell::new(Weak::new()),
            // h: Weak::new(),
            // v: Weak::new(),
        }
    }

    pub fn set_edge(&self, h: Rc<Edge>, v: Rc<Edge>) {
        // self.h = Rc::downgrade(&h);
        // self.v = Rc::downgrade(&v);
        *self.h.borrow_mut() = Rc::downgrade(&h);
        *self.v.borrow_mut() = Rc::downgrade(&v);
    }
}

#[derive(Debug)]
pub struct Edge {
    // point: Vec<Rc<Point>>,
    left: Rc<Point>,
    right: Rc<Point>,
    center: Rc<Point>,
}

impl Edge {
    // fn default() -> Self {
    //     Edge{
    //         point: Vec::<Rc<Point>>::with_capacity(0)
    //     }
    // }
    
    pub fn new(left: Rc<Point>, center: Rc<Point>, right: Rc<Point>) -> Edge {
        Edge {
            left,
            right,
            center
        }
    }
}


pub struct Chessboard {
    points: Vec<Rc<Point>>,
    lines: Vec<Rc<Edge>>,
}

impl Chessboard {
    pub fn new() -> Chessboard {
        let mut p0 = Rc::new(Point::new(0u8));
        let mut p1 = Rc::new(Point::new(1u8));
        let mut p2 = Rc::new(Point::new(2u8));
        let mut p3 = Rc::new(Point::new(3u8));
        let mut p4 = Rc::new(Point::new(4u8));
        let mut p5 = Rc::new(Point::new(5u8));
        let mut p6 = Rc::new(Point::new(6u8));
        let mut p7 = Rc::new(Point::new(7u8));
        let mut p8 = Rc::new(Point::new(8u8));
        let mut p9 = Rc::new(Point::new(9u8));
        let mut p10 = Rc::new(Point::new(10u8));
        let mut p11 = Rc::new(Point::new(11u8));
        let mut p12 = Rc::new(Point::new(12u8));
        let mut p13 = Rc::new(Point::new(13u8));
        let mut p14 = Rc::new(Point::new(14u8));
        let mut p15 = Rc::new(Point::new(15u8));
        let mut p16 = Rc::new(Point::new(16u8));
        let mut p17 = Rc::new(Point::new(17u8));
        let mut p18 = Rc::new(Point::new(18u8));
        let mut p19 = Rc::new(Point::new(19u8));
        let mut p20 = Rc::new(Point::new(20u8));
        let mut p21 = Rc::new(Point::new(21u8));
        let mut p22 = Rc::new(Point::new(22u8));
        let mut p23 = Rc::new(Point::new(23u8));
        let mut p24 = Rc::new(Point::new(24u8));

        // let l01 = Rc::new(Edge::new(points[0].clone(), points[1].clone(), points[2].clone()));
        // let l02 = Rc::new(Edge::new(points[2].clone(), points[3].clone(), points[4].clone()));
        // let l03 = Rc::new(Edge::new(points[4].clone(), points[5].clone(), points[6].clone()));
        // let l04 = Rc::new(Edge::new(points[6].clone(), points[7].clone(), points[0].clone()));
        // let l05 = Rc::new(Edge::new(points[8].clone(), points[9].clone(), points[10].clone()));
        // let l06 = Rc::new(Edge::new(points[10].clone(), points[11].clone(), points[12].clone()));
        // let l07 = Rc::new(Edge::new(points[12].clone(), points[13].clone(), points[14].clone()));
        // let l08 = Rc::new(Edge::new(points[14].clone(), points[15].clone(), points[8].clone()));
        // let l09 = Rc::new(Edge::new(points[16].clone(), points[17].clone(), points[18].clone()));
        // let l10 = Rc::new(Edge::new(points[18].clone(), points[19].clone(), points[20].clone()));
        // let l11 = Rc::new(Edge::new(points[20].clone(), points[21].clone(), points[22].clone()));
        // let l12 = Rc::new(Edge::new(points[22].clone(), points[23].clone(), points[16].clone()));
        // let l13 = Rc::new(Edge::new(points[1].clone(), points[9].clone(), points[17].clone()));
        // let l14 = Rc::new(Edge::new(points[3].clone(), points[11].clone(), points[19].clone()));
        // let l15 = Rc::new(Edge::new(points[5].clone(), points[13].clone(), points[21].clone()));
        // let l16 = Rc::new(Edge::new(points[7].clone(), points[15].clone(), points[23].clone()));

        let l01 = Rc::new(Edge::new(p0.clone(), p1.clone(), p2.clone()));
        let l02 = Rc::new(Edge::new(p2.clone(), p3.clone(), p4.clone()));
        let l03 = Rc::new(Edge::new(p4.clone(), p5.clone(), p6.clone()));
        let l04 = Rc::new(Edge::new(p6.clone(), p7.clone(), p0.clone()));
        let l05 = Rc::new(Edge::new(p8.clone(), p9.clone(), p10.clone()));
        let l06 = Rc::new(Edge::new(p10.clone(), p11.clone(), p12.clone()));
        let l07 = Rc::new(Edge::new(p12.clone(), p13.clone(), p14.clone()));
        let l08 = Rc::new(Edge::new(p14.clone(), p15.clone(), p8.clone()));
        let l09 = Rc::new(Edge::new(p16.clone(), p17.clone(), p18.clone()));
        let l10 = Rc::new(Edge::new(p18.clone(), p19.clone(), p20.clone()));
        let l11 = Rc::new(Edge::new(p20.clone(), p21.clone(), p22.clone()));
        let l12 = Rc::new(Edge::new(p22.clone(), p23.clone(), p16.clone()));
        let l13 = Rc::new(Edge::new(p1.clone(), p9.clone(), p17.clone()));
        let l14 = Rc::new(Edge::new(p3.clone(), p11.clone(), p19.clone()));
        let l15 = Rc::new(Edge::new(p5.clone(), p13.clone(), p21.clone()));
        let l16 = Rc::new(Edge::new(p7.clone(), p15.clone(), p23.clone()));

        // points[0].set_edge(l01.clone(), l04.clone());
        // points[1].set_edge(l01.clone(), l13.clone());
        // points[2].set_edge(l01.clone(), l02.clone());
        // points[3].set_edge(l02.clone(), l14.clone());
        // points[4].set_edge(l02.clone(), l03.clone());
        // points[5].set_edge(l03.clone(), l15.clone());
        // points[6].set_edge(l03.clone(), l04.clone());
        // points[7].set_edge(l04.clone(), l16.clone());
        // points[8].set_edge(l05.clone(), l08.clone());
        // points[9].set_edge(l05.clone(), l13.clone());
        // points[10].set_edge(l06.clone(), l05.clone());
        // points[11].set_edge(l06.clone(), l14.clone());
        // points[12].set_edge(l07.clone(), l06.clone());
        // points[13].set_edge(l07.clone(), l15.clone());
        // points[14].set_edge(l08.clone(), l07.clone());
        // points[15].set_edge(l08.clone(), l16.clone());
        // points[16].set_edge(l09.clone(), l12.clone());
        // points[17].set_edge(l09.clone(), l13.clone());
        // points[18].set_edge(l10.clone(), l09.clone());
        // points[19].set_edge(l10.clone(), l14.clone());
        // points[20].set_edge(l11.clone(), l10.clone());
        // points[21].set_edge(l11.clone(), l15.clone());
        // points[22].set_edge(l12.clone(), l11.clone());
        // points[23].set_edge(l12.clone(), l16.clone());

        p0.set_edge(l01.clone(), l04.clone());
        p1.set_edge(l01.clone(), l13.clone());
        p2.set_edge(l01.clone(), l02.clone());
        p3.set_edge(l02.clone(), l14.clone());
        p4.set_edge(l02.clone(), l03.clone());
        p5.set_edge(l03.clone(), l15.clone());
        p6.set_edge(l03.clone(), l04.clone());
        p7.set_edge(l04.clone(), l16.clone());
        p8.set_edge(l05.clone(), l08.clone());
        p9.set_edge(l05.clone(), l13.clone());
        p10.set_edge(l06.clone(), l05.clone());
        p11.set_edge(l06.clone(), l14.clone());
        p12.set_edge(l07.clone(), l06.clone());
        p13.set_edge(l07.clone(), l15.clone());
        p14.set_edge(l08.clone(), l07.clone());
        p15.set_edge(l08.clone(), l16.clone());
        p16.set_edge(l09.clone(), l12.clone());
        p17.set_edge(l09.clone(), l13.clone());
        p18.set_edge(l10.clone(), l09.clone());
        p19.set_edge(l10.clone(), l14.clone());
        p20.set_edge(l11.clone(), l10.clone());
        p21.set_edge(l11.clone(), l15.clone());
        p22.set_edge(l12.clone(), l11.clone());
        p23.set_edge(l12.clone(), l16.clone());

        // p0.borrow_mut().set_edge(l01.clone(), l04.clone());
        // p1.borrow_mut().set_edge(l01.clone(), l13.clone());
        // p2.borrow_mut().set_edge(l01.clone(), l02.clone());
        // p3.borrow_mut().set_edge(l02.clone(), l14.clone());
        // p4.borrow_mut().set_edge(l02.clone(), l03.clone());
        // p5.borrow_mut().set_edge(l03.clone(), l15.clone());
        // p6.borrow_mut().set_edge(l03.clone(), l04.clone());
        // p7.borrow_mut().set_edge(l04.clone(), l16.clone());
        // p8.borrow_mut().set_edge(l05.clone(), l08.clone());
        // p9.borrow_mut().set_edge(l05.clone(), l13.clone());
        // p10.borrow_mut().set_edge(l06.clone(), l05.clone());
        // p11.borrow_mut().set_edge(l06.clone(), l14.clone());
        // p12.borrow_mut().set_edge(l07.clone(), l06.clone());
        // p13.borrow_mut().set_edge(l07.clone(), l15.clone());
        // p14.borrow_mut().set_edge(l08.clone(), l07.clone());
        // p15.borrow_mut().set_edge(l08.clone(), l16.clone());
        // p16.borrow_mut().set_edge(l09.clone(), l12.clone());
        // p17.borrow_mut().set_edge(l09.clone(), l13.clone());
        // p18.borrow_mut().set_edge(l10.clone(), l09.clone());
        // p19.borrow_mut().set_edge(l10.clone(), l14.clone());
        // p20.borrow_mut().set_edge(l11.clone(), l10.clone());
        // p21.borrow_mut().set_edge(l11.clone(), l15.clone());
        // p22.borrow_mut().set_edge(l12.clone(), l11.clone());
        // p23.borrow_mut().set_edge(l12.clone(), l16.clone());

        // (*p0).set_edge(l01.clone(), l04.clone());
        // (*p1).set_edge(l01.clone(), l13.clone());
        // (*p2).set_edge(l01.clone(), l02.clone());
        // (*p3).set_edge(l02.clone(), l14.clone());
        // (*p4).set_edge(l02.clone(), l03.clone());
        // (*p5).set_edge(l03.clone(), l15.clone());
        // (*p6).set_edge(l03.clone(), l04.clone());
        // (*p7).set_edge(l04.clone(), l16.clone());
        // (*p8).set_edge(l05.clone(), l08.clone());
        // (*p9).set_edge(l05.clone(), l13.clone());
        // (*p10).set_edge(l06.clone(), l05.clone());
        // (*p11).set_edge(l06.clone(), l14.clone());
        // (*p12).set_edge(l07.clone(), l06.clone());
        // (*p13).set_edge(l07.clone(), l15.clone());
        // (*p14).set_edge(l08.clone(), l07.clone());
        // (*p15).set_edge(l08.clone(), l16.clone());
        // (*p16).set_edge(l09.clone(), l12.clone());
        // (*p17).set_edge(l09.clone(), l13.clone());
        // (*p18).set_edge(l10.clone(), l09.clone());
        // (*p19).set_edge(l10.clone(), l14.clone());
        // (*p20).set_edge(l11.clone(), l10.clone());
        // (*p21).set_edge(l11.clone(), l15.clone());
        // (*p22).set_edge(l12.clone(), l11.clone());
        // (*p23).set_edge(l12.clone(), l16.clone());

        Chessboard{
            points: vec![p0.clone(),
                         p1.clone(),
                         p2.clone(),
                         p3.clone(),
                         p4.clone(),
                         p5.clone(),
                         p6.clone(),
                         p7.clone(),
                         p8.clone(),
                         p9.clone(),
                         p10.clone(),
                         p11.clone(),
                         p12.clone(),
                         p13.clone(),
                         p14.clone(),
                         p15.clone(),
                         p16.clone(),
                         p17.clone(),
                         p18.clone(),
                         p19.clone(),
                         p20.clone(),
                         p21.clone(),
                         p22.clone(),
                         p23.clone(),
                         p24.clone(),],
            lines: vec![l01.clone(),
                        l02.clone(),
                        l03.clone(),
                        l04.clone(),
                        l05.clone(),
                        l06.clone(),
                        l07.clone(),
                        l08.clone(),
                        l09.clone(),
                        l10.clone(),
                        l11.clone(),
                        l12.clone(),
                        l13.clone(),
                        l14.clone(),
                        l15.clone(),
                        l16.clone()],
        }
    }
}